#include "globalvar.h"
char* memstr(char* full_data,char* substr,int full_data_len=tableSize)
{
  if (full_data == NULL || full_data_len <= 0 || substr == NULL)
      return NULL; 
  if (*substr == '\0')
      return NULL; 
  int sublen = strlen(substr);
  int i;
  char* cur = full_data;
  int last_possible = full_data_len - sublen + 1;
  for (i = 0; i < last_possible; i++) {
    if (*cur == *substr)
      if (memcmp(cur, substr, sublen) == 0)
        return cur;
    cur++;
  }
  return NULL;
}
void pushSymb(char* name,char* val){
  int lenName=strlen(name);
  int lenVal=strlen(val);
  
  if(lenName){
    char *tmp=(char*)calloc(lenName+4,sizeof(char));
    sprintf(tmp,"\2%s\1\1",name);
    char*p=memstr(topTable,tmp);
    char **addr;
    if(p){
      char  Stick[3]="\3\3";
      char* currTopTable=memstr(topTable,Stick);
      if(currTopTable&&currTopTable>p){
        p+=lenName+3;
        addr=(char**)p;
        *addr=(char*)realloc(*addr,lenVal+1);
        strcpy(*addr,val);
        goto PushSymbOver;
      }
    }
    *(--topTable)=2;
    topTable-=sizeof(char*);
    addr=(char**)topTable;
    *addr=(char*)calloc(lenVal+1,sizeof(char));
    strcpy(*addr,val);
    *(--topTable)=1;*(--topTable)=1;
    topTable-=lenName;
    memcpy(topTable,name,lenName);
    *(--topTable)=2;
    tableSize+=4+sizeof(char*)+lenName;
  PushSymbOver: 
    free(tmp);
    tmp=topTable;
    
  }


}
char findSymb(At a){
  int len=strlen(a.t);
  if(len){
    sprintf(a.w,"\2%s\1\1",a.t);
    char*p=memstr(topTable,a.w);
    if(p){
        p+=len+3;
        char**addr=(char**)p;
        if(*addr&&*(p+sizeof(char*))==2){
          strcpy(a.w,*addr);
          return 0;
        }else{
          *(a.w)='\0';
          return 1;
        }
    }
  }
  a.w[0]='\0';
  return 1;
}
void pushTable(){*(--topTable)=3;*(--topTable)=3;tableSize+=2;}
void popTable(char *endTable){
  char* maxTable=(endTable ? endTable : (symTable+MAXTABLESIZE))\
                  -3-sizeof(char*);
  while(topTable<=maxTable){
    if(topTable[0]==3&&topTable[1]==3){
      maxTable=NULL;
      topTable+=2;
      break;
    }else if(topTable[0]==1&&topTable[1]==1&&topTable[sizeof(char*)+2]==2){
      char** addr=(char**)(topTable+2);
      if(*addr)free(*addr);
      topTable+=sizeof(char*)+3;
      continue;
    }
    ++topTable;
  }
  if(maxTable){
    topTable=endTable ? endTable : (symTable+MAXTABLESIZE-1);
  }
  tableSize=symTable+MAXTABLESIZE-1-topTable;
}
/*test
int main(){
  char* s=(char*)malloc(256);
  char* name=(char*)malloc(256);
  char* val=(char*)malloc(256);
  char* writeOverAt=s;
  while(true){
    scanf("%s %s",name,val);
    char ret=findSymb(name,s,&writeOverAt);
    if(ret){pushSymb(name,val);pushTable();}else{popTable();}
    printf("ret[%d]:over[%ld]:%s\n",ret,writeOverAt-s,s);
    char*p=topTable;
    while(*p!='\0')printf("%c",*(p++));
    printf("\n");
        pushTable();
    char an[10]="x";
    char bn[10]="y";
    char av[10]="abc";
    char bv[10]="bcd";
    table();
    pushSymb(an,av);
    table();
    printf("%d,%s\n",findSymb({NULL,out,an,0,0}),out);
    pushSymb(an,bv); 
    table();   
    printf("%d,%s\n",findSymb({NULL,out,an,0,0}),out);
    popTable();
    table();
    printf("%d,%s\n",findSymb({NULL,out,an,0,0}),out);
    pushTable();
    pushSymb(an,av);
    table();
    printf("%d,%s\n",findSymb({NULL,out,an,0,0}),out);
    pushSymb(bn,av);
    table();
    printf("%d,%s\n",findSymb({NULL,out,an,0,0}),out);
    pushSymb(an,bv);
    table();
    printf("%d,%s\n",findSymb({NULL,out,an,0,0}),out);
    popTable();
    table();
  }
}*/
